<?php


namespace App\Businesses;

use App\Constant\FrontendConstant;
use App\Exceptions\ServiceException;
use App\Services\Base\Interfaces\ConfigServiceInterface;
use App\Services\Base\Services\ConfigService;
use App\Services\Business\Interfaces\AnthologyServiceInterface;
use App\Services\Business\Interfaces\ComboServiceInterface;
use App\Services\Business\Interfaces\CourseServiceInterface;
use App\Services\Business\Interfaces\GroupServiceInterface;
use App\Services\Business\Interfaces\PaperServiceInterface;
use App\Services\Business\Models\Anthology;
use App\Services\Business\Models\Combo;
use App\Services\Business\Models\Course;
use App\Services\Business\Models\Paper;
use App\Services\Business\Models\Question;
use App\Services\Business\Models\Video;
use App\Services\Business\Services\AnthologyService;
use App\Services\Business\Services\ComboService;
use App\Services\Business\Services\BusinessService;
use App\Services\Business\Services\GroupService;
use App\Services\Business\Services\PaperService;
use App\Services\Member\Interfaces\RoleServiceInterface;
use App\Services\Member\Interfaces\SocialiteServiceInterface;
use App\Services\Member\Interfaces\UserServiceInterface;
use App\Services\Member\Services\RoleService;
use App\Services\Member\Services\SocialiteService;
use App\Services\Member\Services\UserService;
use App\Services\Order\Interfaces\OrderServiceInterface;
use App\Services\Order\Interfaces\PromoCodeServiceInterface;
use App\Services\Order\Services\OrderService;
use App\Services\Order\Services\PromoCodeService;
use App\Services\Other\Models\WechatPlatform;
use App\Services\Company\Interfaces\CompanyOrderServiceInterface;
use App\Services\Company\Interfaces\CompanyServiceInterface;
use App\Services\Company\Services\CompanyOrderService;
use App\Services\Company\Services\CompanyService;
use Carbon\Carbon;

class BusinessState
{






    /**
     * 订单是否支付.
     *
     * @param array $order
     *
     * @return bool
     */
    public function orderIsPaid(array $order): bool
    {
        return $order['status'] === FrontendConstant::ORDER_PAID;
    }

    /**
     * 是否需要绑定手机号
     *
     * @param array $user
     * @return bool
     */
    public function isNeedBindMobile(array $user): bool
    {
        return substr($user['mobile'], 0, 1) != 1 || mb_strlen($user['mobile']) !== 11;
    }

    /**
     * @param array $user
     * @return bool
     */
    public function isRole(array $user): bool
    {
        if (!$user['role_id'] || !$user['expired_at']) {
            return false;
        }
        if (Carbon::now()->gt($user['expired_at'])) {
            return false;
        }
        return true;
    }

    public function isMember(array $user): bool
    {
        /**
         * @var $userService UserService
         */
        $userService = app()->make(UserServiceInterface::class);

        if ($userService->hasCourseMember($user['id'])) {
            return true;
        }
        if ($userService->hasComboMember($user['id'])) {
            return true;
        }
        if ($userService->hasRoleMember($user['id'])) {
            return true;
        }
        if ($userService->hasGroupMember($user['id'])) {
            return true;
        }


        return false;

    }

    /**
     * @param array $shop
     * @return bool
     */
    public function isCompanyExpired(array $shop): bool
    {

        if (!$shop['role_id'] || !$shop['expired_at']) {
            return false;
        }
        if (Carbon::now()->gt($shop['expired_at'])) {
            return false;
        }
        return true;
    }


    public function isBindMini(array $shop)
    {
        return WechatPlatform::query()->where('company_id', $shop['id'])->exists();

    }


    /**
     * @param int $userId
     * @param int $shopId
     * @return bool
     */
    public function isCompanyRole(int $userId, int $shopId): bool
    {
        /**
         * @var $roleService RoleService
         */
        $roleService = app()->make(RoleServiceInterface::class);

        $role = $roleService->findCompanyRole($userId, $shopId);

        if (!$role) {
            return false;
        }
        if (!$role['role_id'] || !$role['expired_at']) {
            return false;
        }
        if (Carbon::now()->gt($role['expired_at'])) {
            return false;
        }
        return true;
    }




    /**
     * 是否可以生成邀请码
     *
     * @param array $user
     * @return bool
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function canGenerateInviteCode(array $user): bool
    {
        /**
         * @var $configService ConfigService
         */
        $configService = app()->make(ConfigServiceInterface::class);
        /**
         * @var $promoCodeService PromoCodeService
         */
        $promoCodeService = app()->make(PromoCodeServiceInterface::class);
        $inviteConfig = $configService->getMemberInviteConfig();
        $isMember = $this->isMember($user);
        if ((bool)$inviteConfig['free_user_enabled'] === false && !$isMember) {
            // 开启了非会员无法生成优惠码
            return false;
        }
        $userPromoCode = $promoCodeService->userPromoCode($user['id']);
        if ($userPromoCode) {
            // 已经生成
            return false;
        }
        return true;
    }

    /**
     * @param int $loginUserId
     * @param array $promoCode
     * @return bool
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function promoCodeCanUse(int $loginUserId, array $promoCode): bool
    {
        // 自己不能使用自己的优惠码
        if ($promoCode['user_id'] === $loginUserId && strtolower($promoCode[0]) === 'u') {
            return false;
        }
        if ($promoCode['use_times'] > 0 && $promoCode['use_times'] - $promoCode['used_times'] <= 0) {
            // 使用次数已用完
            return false;
        }
        //这里过期时间不为空,而且现在的时间已经大于过期的时间，优惠码就已经过期
        if ($promoCode['expired_at'] && Carbon::now()->gt($promoCode['expired_at'])) {
            return false;
        }
        /**
         * @var $promoCodeService PromoCodeService
         */
        $promoCodeService = app()->make(PromoCodeServiceInterface::class);
        // 同一邀请码一个用户只能用一次
        $useRecords = $promoCodeService->getCurrentUserOrderPaidRecords($loginUserId, $promoCode['id']);
        if ($useRecords) {
            return false;
        }
        // 非用户邀请优惠码可以多次使用
        if (!$this->isUserInvitePromoCode($promoCode['code'])) {
            return true;
        }

        return true;
    }

    public function couponCanUse(int $loginUserId, array $coupon, array $userCoupon): bool
    {

        if ($coupon['use_times'] > 0 && $coupon['use_times'] - $coupon['used_times'] <= 0) {
            // 使用次数已用完
            return false;
        }
        if (Carbon::now()->lt($userCoupon['start_time']) || Carbon::now()->gt($userCoupon['end_time'])) {
            return false;
        }


        return true;
    }

    public function redeemCodeCanUse(array $code): bool
    {

        if ($code['use_times'] > 0 && $code['use_times'] - $code['used_times'] <= 0) {
            // 使用次数已用完
            return false;
        }
        if (Carbon::now()->lt($code['start_time']) || Carbon::now()->gt($code['end_time'])) {
            return false;
        }


        return true;
    }


    /**
     * @param string $code
     * @return bool
     */
    public function isUserInvitePromoCode(string $code): bool
    {
        return strtolower($code[0]) === 'u';
    }

    /**
     * @param array $order
     * @return int
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function calculateOrderNeedPaidSum(array $order): int
    {

        //这里用户用的订单

        /**
         * @var $orderService OrderService
         */
        $orderService = app()->make(OrderServiceInterface::class);
        $discountSum = $orderService->getOrderPaidRecordsTotal($order['id']);


        $sum = $order['charge'] - $discountSum;
        return $sum >= 0 ? $sum : 0;
    }


    public function isBuyPaper(int $userId, int $paperId): bool
    {

        if (!$userId) {
            return false;
        }
        /**
         * @var PaperService $paperService
         *
         */
        $paperService = app()->make(PaperServiceInterface::class);
        $paper = $paperService->find($paperId);
        if ($paper['is_free'] === Paper::IS_FREE_YES) {
            return true;
        }
        /**
         * @var $userService UserService
         */
        $userService = app()->make(UserServiceInterface::class);
        if ($userService->hasPaper($userId, $paperId)) {
            return true;
        }
        if ($this->isCompanyRole($userId, $paper['company_id'])) {
            return true;
        }


        return false;

    }




    /**
     * 是否可以评论课程
     *
     * @param array $user
     * @param array $course
     * @return bool
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function courseCanComment(array $user, array $course): bool
    {
        if (!$user) {
            return false;
        }
        if ($this->isBuyCourse($user['id'], $course['id'])) {
            return true;
        }
        return false;
    }

    public function anthologyCanComment(array $user, array $anthology): bool
    {
        if (!$user) {
            return false;
        }
        if ($this->isBuyAnthology($user['id'], $anthology['id'])) {
            return true;
        }
        return false;
    }

    public function articleCanComment(array $user, array $article): bool
    {

        //todo not fiished yet
        return true;

    }

    public function videoCanComment(array $user, array $video): bool
    {
        if (!$user) {
            return false;
        }

        if ($this->canSeeVideo($user, $video)) {
            return true;
        }
        return false;
    }

    /**
     * 是否开启微信公众号授权登录
     *
     * @return bool
     */
    public function isEnabledMpOAuthLogin(): bool
    {
        /**
         * @var ConfigService $configService
         */
        $configService = app()->make(ConfigServiceInterface::class);
        $mpWechatConfig = $configService->getMpWechatConfig();
        $enabledOAuthLogin = (int)($mpWechatConfig['enabled_oauth_login'] ?? 0);
        return $enabledOAuthLogin === 1;
    }

    /**
     * @return bool
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function enabledMpScanLogin(): bool
    {
        /**
         * @var ConfigService $configService
         */
        $configService = app()->make(ConfigServiceInterface::class);

        $mpWechatConfig = $configService->getMpWechatConfig();

        $enabledOAuthLogin = (int)($mpWechatConfig['enabled_scan_login'] ?? 0);

        return $enabledOAuthLogin === 1;
    }

    public function socialiteBindCheck(int $userId, string $app, string $appId): void
    {
        /**
         * @var SocialiteService $socialiteService
         */
        $socialiteService = app()->make(SocialiteServiceInterface::class);

        $hasBindSocialites = $socialiteService->userSocialites($userId);
        if (in_array($app, array_column($hasBindSocialites, 'app'))) {
            throw new ServiceException(__('您已经绑定了该渠道的账号'));
        }

        // 读取当前社交账号绑定的用户id
        if ($socialiteService->getBindUserId($app, $appId)) {
            throw new ServiceException(__('当前渠道账号已绑定了其它账号'));
        }
    }
}
